package com.gitee.wsl.common.script

import com.googlecode.aviator.AviatorEvaluator

fun ruleEngine(config:RuleScope.()->Unit):RuleEngine{
    val ruleList= mutableListOf<Rule>()
    val ruleContext=RuleContext()
    val scope=object :RuleScope{
        override fun init(block: RuleContext.() -> Unit) {
           block(ruleContext)
        }

        override fun rule( name:String, expression: String, hitDesc:String) {
            ruleList.add(Rule(name, expression, hitDesc))
        }
    }
    return RuleEngine(ruleContext,ruleList)
}

interface RuleScope{

    fun init(block:RuleContext.()->Unit)

    fun rule( name:String, expression: String, hitDesc:String="")

}

class RuleEngine(val ruleContext: RuleContext,val rules: List<Rule>) {

    fun executeRule(): RuleExecuteResult {
        //init param
        val result = RuleExecuteResult()
        result.resultType=RuleExecuteResultEnum.PASS
        val hitDesc: MutableList<String> = result.hitDesc

        val map: MutableMap<String, Any> = ruleContext.params
        ruleContext.data?.let {
            map["entity"] = it
        }

        //循环执行每条逻辑，并组装返回结果
        for (rule in rules) {
            val hit = AviatorEvaluator.execute(rule.expression, map, true) as Boolean
            if (hit) {
                //log.info("hit rule: {}", rule.getHitDesc())
                result.resultType=RuleExecuteResultEnum.REFUSE
                hitDesc.add(rule.hitDesc)
            }
        }
        return result
    }

}

data class Rule(val name:String,
                val expression: String,
                val hitDesc:String=""
)

class RuleContext{
    val data:Any?=null

    var params= mutableMapOf<String,Any>()
}

class RuleExecuteResult{
    var resultType:RuleExecuteResultEnum = RuleExecuteResultEnum.PASS
    val hitDesc: MutableList<String> = mutableListOf()
}

enum class RuleExecuteResultEnum{
    PASS,
    REFUSE
}